package dispatcher.group.gui.elevator;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import observer.ElevatorPartialStruct;
import state.Globals;
import system.Constant;

import dispatcher.gui.state.GroupDispatcherStateHandler;

/**
 * This class is the graphics representation of the elevator. It encompasses the elevator
 * shaft and the elevator car.
 * @author Caleb
 *
 */
public class ElevatorPanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 589427731609089335L;
	private int elevatorNumber;
	
	private ElevatorCar car;
	private int maxFloors;
	
	private static final int DEFAULT_FLOOR_HEIGHT = 100; 
	private static final int DEFAULT_SHAFT_WIDTH = 75;
	
	/**
	 * The main constructor
	 * @param elevatorNumber The elevator ID this grphics is associated with
	 */
	public ElevatorPanel(int elevatorNumber){
		// Graps the max number of floors in the system
		this.maxFloors = GroupDispatcherStateHandler.getInstance().getMaxFloors();
		
		this.elevatorNumber = elevatorNumber;
		
		// Set the fixed size of the panel
		this.setPreferredSize(new Dimension(DEFAULT_SHAFT_WIDTH, (this.maxFloors + 1) * DEFAULT_FLOOR_HEIGHT + 50));
		this.setMaximumSize(new Dimension(DEFAULT_SHAFT_WIDTH, (this.maxFloors + 1) * DEFAULT_FLOOR_HEIGHT + 50));
		
		createElevatorShaft();
	}
	
	/**
	 * This method return is the elevator ID associated with this graphic
	 * @return Returns the elevator ID
	 */
	public int getElevatorId(){
		return elevatorNumber;
	}
	
	/**
	 * This method will add and elevator to the shaft
	 */
	public void addElevatorCar(){
		car = new ElevatorCar((byte)this.elevatorNumber);
	}
	
	/**
	 * This method will create the elevator shaft
	 */
	private void createElevatorShaft(){
		// Border used to create illusion that the area is inclosed
		TitledBorder shaft = null;
		if (elevatorNumber == 0){
			shaft = BorderFactory.createTitledBorder("Lobby");	
		}else{
			shaft = BorderFactory.createTitledBorder("" + elevatorNumber);
		}
		
		shaft.setTitleJustification(TitledBorder.CENTER);
		shaft.setTitleColor(Color.BLACK);
		this.setBorder(shaft);
	}
	
	/**
	 * A custom paint method
	 */
	@Override
	public void paint(Graphics g){
		super.paint(g);
		
		// This will draw the lines denoting the top and bottom of a given floor
		g.setColor(Color.BLACK);
		for(int i = this.maxFloors + 1; i > 0; i--){
		
			g.drawLine(0, i * DEFAULT_FLOOR_HEIGHT, DEFAULT_SHAFT_WIDTH, i * DEFAULT_FLOOR_HEIGHT);
		}
		// This will query the elevator last known floor data and set the elevator car at that location
		if (car != null){
			ElevatorPartialStruct struct = GroupDispatcherStateHandler.getInstance().getElevatorStatus((byte)elevatorNumber);
			int currentFloor = 0;
			synchronized(struct){
				currentFloor = maxFloors - (int)struct.getLastKnownFloor() + Constant.DEFAULT_FLOOR_START;
			}
			car.setLocation(12, currentFloor * DEFAULT_FLOOR_HEIGHT + 10);
			car.paint(g);
		}else{
			Globals.getLogger().error("Elevator Panel : " + this.elevatorNumber + " was created without elevator car");
		}
	} 
}
